import SparkMD5 from "spark-md5";
/**
 * 收钱吧签名
 * 签名算法：

1 筛选 获取所有非空的参数，剔除 sign
2 排序 将筛选的参数按照第一个字符的键值ASCII码递增排序（字母升序排序），如果遇到相同字符则按照第二个字符的键值ASCII码递增排序，以此类推。
3 拼接 将排序后的参数与其对应值，组合成“参数=参数值”的格式，并且把这些参数用&字符连接起来，此时生成的字符串为待签名字符串。
 将key的值拼接在字符串后面，调用MD5算法生成sign。将sign转换成大写。
 * @param {any} params 
 * @param {string} key 
 * @return 
 */
export function getSqbSign(params, key) {
  // 筛选和排序参数
  let sortedParams = Object.keys(params)
    .filter((key) => key !== "sign" && params[key]) // 剔除sign和空
    .sort((a, b) => {
      return a.localeCompare(b); // 字母升序排序
    })
    .map((key) => `${key}=${params[key]}`); // 组合成“参数=参数值”的格式

  // 生成sign
  let signString = sortedParams.join("&") + `&key=${key}`; // 拼接key
  // console.log('----signString:', signString)
  let sign = SparkMD5.hash(signString).toUpperCase(); // MD5算法生成sign并转换为大写
  return sign;
}

/**
 * 钱吧支付签名算法
 * @param {Object} params 待签名参数对象
 * @param {string} merchantKey 商户密钥
 * @returns {string} 32位大写MD5签名
 */
export function qianbaSign(params, merchantKey) {
  // 1. 过滤空值参数并排序
  const sortedKeys = Object.keys(params)
    .filter(
      (key) =>
        params[key] !== "" && params[key] !== null && params[key] !== undefined
    )
    .sort();

  // 2. 拼接键值对
  let stringToSign = "";
  sortedKeys.forEach((key, index) => {
    if (index !== 0) stringToSign += "&";
    stringToSign += `${key}=${params[key]}`;
  });

  // 3. 添加商户密钥
  stringToSign += `&key=${merchantKey}`;

  // 4. 使用SparkMD5生成签名
  const md5Sign = SparkMD5.hash(stringToSign).toUpperCase();

  return md5Sign;
}

/**
 * 钱吧支付签名算法
 * @param {Object} params 原始参数对象
 * @param {string} key 商户密钥
 * @returns {string} 32位大写的MD5签名
 */
export function generateQianbaSign(params, key) {
  // 1. 筛选非空参数并剔除sign
  const filteredParams = {};
  Object.keys(params).forEach((k) => {
    if (
      k !== "sign" &&
      params[k] !== "" &&
      params[k] !== null &&
      params[k] !== undefined
    ) {
      filteredParams[k] = params[k];
    }
  });

  // 2. 按ASCII码升序排序参数
  const sortedKeys = Object.keys(filteredParams).sort((a, b) => {
    const minLength = Math.min(a.length, b.length);
    for (let i = 0; i < minLength; i++) {
      if (a.charCodeAt(i) !== b.charCodeAt(i)) {
        return a.charCodeAt(i) - b.charCodeAt(i);
      }
    }
    return a.length - b.length;
  });

  // 3. 拼接键值对
  let stringToSign = "";
  sortedKeys.forEach((k, index) => {
    if (index !== 0) stringToSign += "&";
    stringToSign += `${k}=${filteredParams[k]}`;
  });

  // 4. 拼接密钥并生成签名
  stringToSign += `&key=${key}`;
  const sign = SparkMD5.hash(stringToSign).toUpperCase();

  return sign;
}
